package com.template.templateuser.auth.serviceauth.config;

/**
 * @author fengpt
 * @createTime 2020年04月17日 12:14:00
 */

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

/**
 */
@Configuration
@EnableSwagger2
public class SwaggerApp implements ResourceServerConfigurer {
    @Value("${template.swagger.author}")
    private String swaggerAuthor;
    @Value("${template.swagger.doc-version}")
    private String docVersion;
    @Value("${template.swagger.title}")
    private String title;
    @Value("${template.swagger.description}")
    private String description;
    @Value("${template.swagger.base-package}")
    private String basePackage;
    @Value("${template.swagger.enabled:false}")
    private boolean enabled;
    @Value("${template.swagger.api-path:}")
    private String apiPath;
    @Value("${template.swagger.host:}")
    private String host;
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {

    }
    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.csrf().disable().exceptionHandling()
                .authenticationEntryPoint(
                        (request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED))
                .and().authorizeRequests()
                .antMatchers("/v2/api-docs", "/favicon.ico", "/webjars/**", "/csrf", "/swagger**",
                        "/swagger-resources/**", "/course/coursebase/**", "/hystrix**", "/hystrix/**", "/proxy.stream",
                        "/organization/{id}/is-available", "/actuator/**", "/actuator", "/druid/**", "/druid",
                        "/order/delivery/{id}/evaluation","/cache","/db","/webservices/**")
                .permitAll().anyRequest().authenticated().and().httpBasic();
    }

    /**
     * swagger 相关的配置
     */
    @Bean
    public Docket swaggerApi() {
        ParameterBuilder ticketPar = new ParameterBuilder();
        List<Parameter> operationParameters = new ArrayList<Parameter>();
        ticketPar.name("Authorization").description("user token").modelRef(new ModelRef("string"))
                .parameterType("header").required(false).build(); // header中的Authorization参数非必填，传空也可以
        operationParameters.add(ticketPar.build());

        return new Docket(DocumentationType.SWAGGER_2).host(host).apiInfo(new ApiInfoBuilder()
                // 文档界面标题
                .title(title)
                // 文档说明
                .description(description)
                // 服务开发者网址
                .termsOfServiceUrl("https://www.fengpt.cn")
                // 作者信息
                .contact(new Contact(swaggerAuthor, "https://www.fengpt.cn", ""))
                // 文档版本
                .version(docVersion).build()).pathMapping(apiPath)
                // 是否开启
                .enable(enabled).select()
                // 扫描的路径包
                .apis(RequestHandlerSelectors.basePackage(basePackage))
                // 指定路径处理PathSelectors.any()代表所有的路径
                .paths(PathSelectors.any()).build()
                // 加入全局参数
                .globalOperationParameters(operationParameters);
    }
}
